#ifndef GX_FINAL_RENDERING_ENTITY_H
#define GX_FINAL_RENDERING_ENTITY_H

#include "Basic/GxLibBasic.h"
#include "APIMacros.h"
#include "Basic/Stream.h"
#include "LibGL/GxMath3D.h"

using namespace GxLibBasic;

namespace FinalRendering
{
	namespace Engine
	{
		class IEntity;
		class IView;

		struct EntityMessage
		{
			const wchar_t * Message;
			Int64 Param;
			EntityMessage();
			EntityMessage(const wchar_t * msg, Int64 param);
		};

		struct PropertyDesc
		{
			const wchar_t * PropertyName;
			const wchar_t * PropertyType;
			void * Value;
		};

		struct Volume
		{
			enum _VolumeType
			{
				Point, Sphere, Rectangle
			} Type;
			vec3 Position;
			vec3 Size;
			float Radius;
		};

		const unsigned int MaskAll = 0xFFFFFFFF;

		class IEngine
		{
		public:
			virtual IEntity * FindEntity(const wchar_t * name) = 0;
			virtual void BroadcastMessage(IEntity * sender, const EntityMessage & msg, unsigned int mask = MaskAll) = 0;
			virtual void BspBroadcastMessage(IEntity * sender, const Volume & vol, const EntityMessage & msg,
				unsigned int mask = MaskAll) = 0;
		};

		class IView
		{
		public:
			enum _ViewType
			{
				Perspective, Left, Top, Front
			};
			virtual _ViewType GetViewType() = 0;

		};

		class IString
		{
		public:
			virtual void SetString(const wchar_t * str) = 0;
			virtual const wchar_t * GetString() = 0;
		};

		class IIntArray
		{
		public:
			virtual int Count()=0;
			virtual int GetValue(int i)=0;
			virtual void Remove(int start, int len)=0;
			virtual void Add(int value)=0;
		};

		//GX_API
		class IEntityDesc
		{
		public:
			virtual const wchar_t * ClassName() = 0;
			virtual IEntity * Create() = 0;
			virtual void Destroy(IEntity * ent) = 0;
			virtual IEntity * Create(Stream * stream) = 0;
		};

		//GX_API
		class IEntity
		{
		public:
			virtual IEntityDesc * GetDesc() = 0;
			virtual bool Serialize(Stream * stream) = 0;
			virtual void EditorDraw(IView * view) = 0;
			virtual int GetPropertyCount() = 0;
			virtual PropertyDesc GetPropertyDesc(int i) = 0;
			virtual const wchar_t * GetName() = 0;
			virtual void SetName(const wchar_t * name) = 0;
			virtual int ProcessMessage(IEntity * sender, EntityMessage msg) = 0;
		};

		//GX_API
		class IBspEntity : public IEntity
		{
		public:
			virtual void Step(float dTime) = 0;
			virtual void GetVolume(Volume * vol) = 0;
		};

		typedef int (GX_API_ENTRY*InitProc)(bool isEditor, IEngine * engine, HMODULE module);
		typedef void (GX_API_ENTRY*DestroyProc)();
		typedef int (GX_API_ENTRY*GetClassesCountProc)();
		typedef IEntityDesc* (GX_API_ENTRY*GetEntityDescProc)(int);
	}
}
#endif